define(["require", "exports", "vscode-languageserver-protocol", "vscode-languageclient/utils/is"], function (require, exports, ls, Is) {
    /* --------------------------------------------------------------------------------------------
     * Copyright (c) Microsoft Corporation. All rights reserved.
     * Licensed under the MIT License. See License.txt in the project root for license information.
     * ------------------------------------------------------------------------------------------ */
    'use strict';
    Object.defineProperty(exports, "__esModule", { value: true });
    var CodeBlock;
    (function (CodeBlock) {
        function is(value) {
            let candidate = value;
            return candidate && Is.string(candidate.language) && Is.string(candidate.value);
        }
        CodeBlock.is = is;
    })(CodeBlock || (CodeBlock = {}));
    function createConverter(vscode, uriConverter) {
        const nullConverter = (value) => vscode.Uri.parse(value);
        const _uriConverter = uriConverter || nullConverter;
        function asUri(value) {
            return _uriConverter(value);
        }
        function asDiagnostics(diagnostics) {
            return diagnostics.map(asDiagnostic);
        }
        function asDiagnostic(diagnostic) {
            let result = new vscode.Diagnostic(asRange(diagnostic.range), diagnostic.message, asDiagnosticSeverity(diagnostic.severity));
            if (Is.number(diagnostic.code) || Is.string(diagnostic.code)) {
                result.code = diagnostic.code;
            }
            if (diagnostic.source) {
                result.source = diagnostic.source;
            }
            if (diagnostic.relatedInformation) {
                result.relatedInformation = asRelatedInformation(diagnostic.relatedInformation);
            }
            return result;
        }
        function asRelatedInformation(relatedInformation) {
            return relatedInformation.map(asDiagnosticRelatedInformation);
        }
        function asDiagnosticRelatedInformation(information) {
            return new vscode.DiagnosticRelatedInformation(asLocation(information.location), information.message);
        }
        function asPosition(value) {
            if (!value) {
                return undefined;
            }
            return new vscode.Position(value.line, value.character);
        }
        function asRange(value) {
            if (!value) {
                return undefined;
            }
            return new vscode.Range(asPosition(value.start), asPosition(value.end));
        }
        function asDiagnosticSeverity(value) {
            if (value === void 0 || value === null) {
                return vscode.DiagnosticSeverity.Error;
            }
            switch (value) {
                case ls.DiagnosticSeverity.Error:
                    return vscode.DiagnosticSeverity.Error;
                case ls.DiagnosticSeverity.Warning:
                    return vscode.DiagnosticSeverity.Warning;
                case ls.DiagnosticSeverity.Information:
                    return vscode.DiagnosticSeverity.Information;
                case ls.DiagnosticSeverity.Hint:
                    return vscode.DiagnosticSeverity.Hint;
            }
            return vscode.DiagnosticSeverity.Error;
        }
        function asHoverContent(value) {
            if (Is.string(value)) {
                return new vscode.MarkdownString(value);
            }
            else if (CodeBlock.is(value)) {
                let result = new vscode.MarkdownString();
                return result.appendCodeblock(value.value, value.language);
            }
            else if (Array.isArray(value)) {
                let result = new vscode.MarkdownString();
                for (let element of value) {
                    if (CodeBlock.is(element)) {
                        result.appendCodeblock(element.value, element.language);
                    }
                    else {
                        result.appendMarkdown(element);
                    }
                }
                return result;
            }
            else {
                let result;
                switch (value.kind) {
                    case ls.MarkupKind.Markdown:
                        return new vscode.MarkdownString(value.value);
                    case ls.MarkupKind.PlainText:
                        result = new vscode.MarkdownString();
                        result.appendText(value.value);
                        return result;
                    default:
                        result = new vscode.MarkdownString();
                        result.appendText(`Unsupported Markup content received. Kind is: ${value.kind}`);
                        return result;
                }
            }
        }
        function asDocumentation(value) {
            if (Is.string(value)) {
                return value;
            }
            else {
                switch (value.kind) {
                    case ls.MarkupKind.Markdown:
                        return new vscode.MarkdownString(value.value);
                    case ls.MarkupKind.PlainText:
                        return value.value;
                    default:
                        return `Unsupported Markup content received. Kind is: ${value.kind}`;
                }
            }
        }
        function asHover(hover) {
            if (!hover) {
                return undefined;
            }
            return new vscode.Hover(asHoverContent(hover.contents), asRange(hover.range));
        }
        function asCompletionResult(result) {
            if (!result) {
                return undefined;
            }
            if (Array.isArray(result)) {
                let items = result;
                return items.map(asCompletionItem);
            }
            let list = result;
            return new vscode.CompletionList(list.items.map(asCompletionItem), list.isIncomplete);
        }
        function asCompletionItemKind(value) {
            // Protocol item kind is 1 based, codes item kind is zero based.
            if (ls.CompletionItemKind.Text <= value && value <= ls.CompletionItemKind.TypeParameter) {
                return [value - 1, undefined];
            }
            ;
            return [vscode.CompletionItemKind.Text, value];
        }
        function asCompletionItem(item) {
            let result = new vscode.CompletionItem(item.label);
            if (item.detail) {
                result.detail = item.detail;
            }
            if (item.documentation) {
                result.documentation = asDocumentation(item.documentation);
                result.documentationFormat = Is.string(item.documentation) ? '$string' : item.documentation.kind;
            }
            ;
            if (item.filterText) {
                result.filterText = item.filterText;
            }
            let insertText = asCompletionInsertText(item);
            if (insertText) {
                result.insertText = insertText.text;
                result.range = insertText.range;
                result.fromEdit = insertText.fromEdit;
            }
            if (Is.number(item.kind)) {
                let [itemKind, original] = asCompletionItemKind(item.kind);
                result.kind = itemKind;
                if (original) {
                    result.originalItemKind = original;
                }
            }
            if (item.sortText) {
                result.sortText = item.sortText;
            }
            if (item.additionalTextEdits) {
                result.additionalTextEdits = asTextEdits(item.additionalTextEdits);
            }
            if (Is.stringArray(item.commitCharacters)) {
                result.commitCharacters = item.commitCharacters.slice();
            }
            if (item.command) {
                result.command = asCommand(item.command);
            }
            if (item.data !== void 0 && item.data !== null) {
                result.data = item.data;
            }
            return result;
        }
        function asCompletionInsertText(item) {
            if (item.textEdit) {
                if (item.insertTextFormat === ls.InsertTextFormat.Snippet) {
                    return { text: new vscode.SnippetString(item.textEdit.newText), range: asRange(item.textEdit.range), fromEdit: true };
                }
                else {
                    return { text: item.textEdit.newText, range: asRange(item.textEdit.range), fromEdit: true };
                }
            }
            else if (item.insertText) {
                if (item.insertTextFormat === ls.InsertTextFormat.Snippet) {
                    return { text: new vscode.SnippetString(item.insertText), fromEdit: false };
                }
                else {
                    return { text: item.insertText, fromEdit: false };
                }
            }
            else {
                return undefined;
            }
        }
        function asTextEdit(edit) {
            if (!edit) {
                return undefined;
            }
            return new vscode.TextEdit(asRange(edit.range), edit.newText);
        }
        function asTextEdits(items) {
            if (!items) {
                return undefined;
            }
            return items.map(asTextEdit);
        }
        function asSignatureHelp(item) {
            if (!item) {
                return undefined;
            }
            let result = new vscode.SignatureHelp();
            if (Is.number(item.activeSignature)) {
                result.activeSignature = item.activeSignature;
            }
            else {
                // activeSignature was optional in the past
                result.activeSignature = 0;
            }
            if (Is.number(item.activeParameter)) {
                result.activeParameter = item.activeParameter;
            }
            else {
                // activeParameter was optional in the past
                result.activeParameter = 0;
            }
            if (item.signatures) {
                result.signatures = asSignatureInformations(item.signatures);
            }
            return result;
        }
        function asSignatureInformations(items) {
            return items.map(asSignatureInformation);
        }
        function asSignatureInformation(item) {
            let result = new vscode.SignatureInformation(item.label);
            if (item.documentation) {
                result.documentation = asDocumentation(item.documentation);
            }
            if (item.parameters) {
                result.parameters = asParameterInformations(item.parameters);
            }
            return result;
        }
        function asParameterInformations(item) {
            return item.map(asParameterInformation);
        }
        function asParameterInformation(item) {
            let result = new vscode.ParameterInformation(item.label);
            if (item.documentation) {
                result.documentation = asDocumentation(item.documentation);
            }
            ;
            return result;
        }
        function asDefinitionResult(item) {
            if (!item) {
                return undefined;
            }
            if (Is.array(item)) {
                return item.map((location) => asLocation(location));
            }
            else {
                return asLocation(item);
            }
        }
        function asLocation(item) {
            if (!item) {
                return undefined;
            }
            return new vscode.Location(_uriConverter(item.uri), asRange(item.range));
        }
        function asReferences(values) {
            if (!values) {
                return undefined;
            }
            return values.map(location => asLocation(location));
        }
        function asDocumentHighlights(values) {
            if (!values) {
                return undefined;
            }
            return values.map(asDocumentHighlight);
        }
        function asDocumentHighlight(item) {
            let result = new vscode.DocumentHighlight(asRange(item.range));
            if (Is.number(item.kind)) {
                result.kind = asDocumentHighlightKind(item.kind);
            }
            return result;
        }
        function asDocumentHighlightKind(item) {
            switch (item) {
                case ls.DocumentHighlightKind.Text:
                    return vscode.DocumentHighlightKind.Text;
                case ls.DocumentHighlightKind.Read:
                    return vscode.DocumentHighlightKind.Read;
                case ls.DocumentHighlightKind.Write:
                    return vscode.DocumentHighlightKind.Write;
            }
            return vscode.DocumentHighlightKind.Text;
        }
        function asSymbolInformations(values, uri) {
            if (!values) {
                return undefined;
            }
            return values.map(information => asSymbolInformation(information, uri));
        }
        function asSymbolKind(item) {
            if (item <= ls.SymbolKind.TypeParameter) {
                // Symbol kind is one based in the protocol and zero based in code.
                return item - 1;
            }
            return vscode.SymbolKind.Property;
        }
        function asSymbolInformation(item, uri) {
            // Symbol kind is one based in the protocol and zero based in code.
            let result = new vscode.SymbolInformation(item.name, asSymbolKind(item.kind), asRange(item.location.range), item.location.uri ? _uriConverter(item.location.uri) : uri);
            if (item.containerName) {
                result.containerName = item.containerName;
            }
            return result;
        }
        function asCommand(item) {
            let result = { title: item.title, command: item.command };
            if (item.arguments) {
                result.arguments = item.arguments;
            }
            return result;
        }
        function asCommands(items) {
            if (!items) {
                return undefined;
            }
            return items.map(asCommand);
        }
        function asCodeLens(item) {
            if (!item) {
                return undefined;
            }
            let result = new vscode.CodeLens(asRange(item.range));
            if (item.command) {
                result.command = asCommand(item.command);
            }
            if (item.data !== void 0 && item.data !== null) {
                result.data = item.data;
            }
            return result;
        }
        function asCodeLenses(items) {
            if (!items) {
                return undefined;
            }
            return items.map((codeLens) => asCodeLens(codeLens));
        }
        function asWorkspaceEdit(item) {
            if (!item) {
                return undefined;
            }
            let result = new vscode.WorkspaceEdit();
            if (item.documentChanges) {
                item.documentChanges.forEach(change => {
                    result.set(_uriConverter(change.textDocument.uri), asTextEdits(change.edits));
                });
            }
            else if (item.changes) {
                Object.keys(item.changes).forEach(key => {
                    result.set(_uriConverter(key), asTextEdits(item.changes[key]));
                });
            }
            return result;
        }
        function asDocumentLink(item) {
            let range = asRange(item.range);
            let target = item.target ? asUri(item.target) : undefined;
            // target must be optional in DocumentLink
            return new vscode.DocumentLink(range, target);
        }
        function asDocumentLinks(items) {
            if (!items) {
                return undefined;
            }
            return items.map(asDocumentLink);
        }
        return {
            asUri,
            asDiagnostics,
            asDiagnostic,
            asRange,
            asPosition,
            asDiagnosticSeverity,
            asHover,
            asCompletionResult,
            asCompletionItem,
            asTextEdit,
            asTextEdits,
            asSignatureHelp,
            asSignatureInformations,
            asSignatureInformation,
            asParameterInformations,
            asParameterInformation,
            asDefinitionResult,
            asLocation,
            asReferences,
            asDocumentHighlights,
            asDocumentHighlight,
            asDocumentHighlightKind,
            asSymbolInformations,
            asSymbolInformation,
            asCommand,
            asCommands,
            asCodeLens,
            asCodeLenses,
            asWorkspaceEdit,
            asDocumentLink,
            asDocumentLinks
        };
    }
    exports.createConverter = createConverter;
});
